import tkinter as tk
import threading
from time import sleep
import ctypes
from ctypes import wintypes
import winsound
import subprocess
import sys
import os
import xml.etree.ElementTree as ET

try:
    base_path = sys._MEIPASS
except Exception:
    base_path = os.path.abspath(".")
wav_path = os.path.join(base_path, "a.wav")

# 定义要执行的命令
command = "powercfg /batteryreport /output battery.xml /xml"
# 使用subprocess模块执行命令
with subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as process:
    stdout, stderr = process.communicate()

# 解析XML文件
tree = ET.parse('battery.xml')
root = tree.getroot()

os.remove('battery.xml')

# 获取命名空间URL，因为XML使用了命名空间
namespace = root.tag[1:].split('}')[0]
ns = {'ns': namespace}
  
# 查找Batteries节中的Battery小节
batteries = root.findall('ns:Batteries/ns:Battery', ns)
  
# 遍历每个Battery小节并打印所需的值
for battery in batteries:
    cycle_count = battery.find('ns:CycleCount', ns).text
    full_charge_capacity = battery.find('ns:FullChargeCapacity', ns).text
    design_capacity = battery.find('ns:DesignCapacity', ns).text
    manufacturer = battery.find('ns:Manufacturer', ns).text

class SYSTEM_POWER_STATUS(ctypes.Structure):
    _fields_ = [
        ('ACLineStatus', wintypes.BYTE),
        ('BatteryFlag', wintypes.BYTE),
        ('BatteryLifePercent', wintypes.BYTE),
    ]

GetSystemPowerStatus = ctypes.windll.kernel32.GetSystemPowerStatus
status = SYSTEM_POWER_STATUS()

# 声明全局变量
window, cap, acst, label_cap, label_pwrst = None, 0, '', None, None

def start_background_task():
    global window, cap, acst
    while not window.closed:  
        if not GetSystemPowerStatus(ctypes.pointer(status)):
            raise ctypes.WinError()
        if status.ACLineStatus == 1:
            acst = 'AC'
        else:
            acst = 'DC'
        cap = status.BatteryLifePercent
        #print("后台任务正在运行...")
        threading.Event().wait(0.5)  # 模拟耗时操作，这里等待0.5秒
    #print("后台任务结束.")

def on_closing():
    global window
    window.closed = True
    window.destroy()

def update_label():
    global window, label_cap, label_pwrst
    label_cap.config(text=f"CAPACITY : {cap}%")
    label_pwrst.config(text=f"POWER STATUS : {acst}")
    if acst == 'AC':
        label_pwrst.config(fg="red")
    else:
        label_pwrst.config(fg="blue")
    window.after(500, update_label)  # 安排下一次更新

def play():
    winsound.PlaySound(wav_path, winsound.SND_FILENAME)
    # 等待播放完成
    while winsound.PlaySound(0, 0):
        pass

def cap_btn_event():
    try:
        cap_ala = int(entry_cap_alarm.get())
        if cap_ala != cap:
            entry_cap_alarm.config(state="disable")
            btn_cap_alarm.config(state="disable")
            btn_cap_alarm.config(text="Running...")
            while cap_ala != cap:
                sleep(1)
            btn_cap_alarm.config(state="normal")
            btn_cap_alarm.config(text="Start")
            entry_cap_alarm.config(state="normal")
            play()
    except:
        pass

def time_btn_event():
    try:
        time_ala = int(entry_time_alarm.get())
        if time_ala > 0:
            entry_time_alarm.config(state="disable")
            btn_time_alarm.config(state="disable")
            btn_time_alarm.config(text="Running...")
            sleep(time_ala * 60)
            btn_time_alarm.config(state="normal")
            btn_time_alarm.config(text="Start")
            entry_time_alarm.config(state="normal")
            play()
    except:
        pass

def cap_btn_click():
    cap_btn_thread = threading.Thread(target=cap_btn_event)
    cap_btn_thread.daemon = True  # 设置为守护线程，当主程序退出时，自动结束线程
    cap_btn_thread.start()  # 启动线程

def time_btn_click():
    time_btn_thread = threading.Thread(target=time_btn_event)
    time_btn_thread.daemon = True  # 设置为守护线程，当主程序退出时，自动结束线程
    time_btn_thread.start()  # 启动线程

def create_window():
    global window, label_cap, label_pwrst, btn_cap_alarm, btn_time_alarm, entry_cap_alarm, entry_time_alarm
    window = tk.Tk()  # 定义root
    window.title("BatteryInfo")
    window.resizable(0, 0)
    window.closed = False
    window.protocol("WM_DELETE_WINDOW", on_closing)

    # 创建并启动后台任务的线程
    background_thread = threading.Thread(target=start_background_task)
    background_thread.daemon = True  # 设置为守护线程，当主程序退出时，自动结束线程
    background_thread.start()

    # 使用grid布局管理器
    label_cycount = tk.Label(window, text=f"CYCLE COUNT : {cycle_count}", font=("Arial", 15))
    label_cycount.grid(row=0, column=1, padx=10, pady=10)
    label_dcap = tk.Label(window, text=f"DESIGN CAPACITY : {design_capacity}", font=("Arial", 15))
    label_dcap.grid(row=1, column=0, padx=10, pady=10)
    label_fcap = tk.Label(window, text=f"FULL CHARGE CAPACITY : {full_charge_capacity}", font=("Arial", 15))
    label_fcap.grid(row=1, column=1, padx=10, pady=10)
    label_manufacturer = tk.Label(window, text=f"MANUFACTURER : {manufacturer}", font=("Arial", 15))
    label_manufacturer.grid(row=2, column=0, padx=10, pady=10)

    frame = tk.Frame(window)
    frame.grid(row=4, column=0, columnspan=2)

    label_cap_alarm = tk.Label(frame, text="ALARMING CAPACITY(%) : ", font=("Arial", 15))
    label_cap_alarm.grid(row=0, column=0, padx=10, pady=10)
    entry_cap_alarm = tk.Entry(frame, width=5, font=("Arial", 15))
    entry_cap_alarm.grid(row=0, column=1, padx=10, pady=10)
    btn_cap_alarm = tk.Button(frame, text="Start", width=10, font=("Arial", 15), command=cap_btn_click)
    btn_cap_alarm.grid(row=0, column=2, padx=10, pady=10)

    label_time_alarm = tk.Label(frame, text="ALARMING TIME(min) : ", font=("Arial", 15))
    label_time_alarm.grid(row=1, column=0, padx=10, pady=10)
    entry_time_alarm = tk.Entry(frame, width=5, font=("Arial", 15))
    entry_time_alarm.grid(row=1, column=1, padx=10, pady=10)
    btn_time_alarm = tk.Button(frame, text="Start", width=10, font=("Arial", 15), command=time_btn_click)
    btn_time_alarm.grid(row=1, column=2, padx=10, pady=10)

    note_frame = tk.Frame(window)
    note_frame.grid(row=5, column=0, columnspan=2)
    label_note = tk.Label(note_frame, text="version 0.9-beta | Feedback : hi@raoyi.net")
    label_note.grid(row=0, column=0, padx=10, pady=10)

    label_cap = tk.Label(window, text=f"CAPACITY : {cap}%", font=("Arial", 15))
    label_cap.grid(row=0, column=0, padx=10, pady=10)
    label_pwrst = tk.Label(window, text=f"POWER STATUS : {acst}", font=("Arial", 20))
    label_pwrst.grid(row=3, column=0, columnspan=2, padx=10, pady=10)

    # 更新全局变量以引用新创建的label
    label_cap, label_pwrst = label_cap, label_pwrst

    update_label()  # 启动第一次更新

    window.mainloop()

if __name__ == "__main__":
    create_window()